package encaps.action;

import encaps.entities.Grant;
import encaps.resources.Image;
import encaps.resources.Labels;
import encaps.resources.Response;
import encaps.utils.StringUtil;
import encaps.utils.SystemException;
import encaps.utils.XMLHelper;
import encaps.utils.search.SearchContext;
import encaps.utils.search.Searcher;
import java.util.HashMap;
import java.util.Map;
import org.jdom.Element;

public class AdvancedMovieSearchAction extends AbstractSearchAction {

    public static final String ADVANCED_MOVIE_SEARCH = "advMovieSearch";
    public static final String TITLE = "title";
    public static final String COUNTRIES = "countries";
    public static final String GENRE = "genre";
    //public static final String ACTOR = "actor";
    //public static final String DIRECTOR = "director";
    //public static final String PRODUCER = "producer";
    public static final String STUDIO = "studio";
    public static final String RATING_MIN = "ratingMin";
    public static final String RATING_MAX = "ratingMax";
    public static final String DESCRIPTION = "descr";
    public static final String BUDGET_MIN = "budgetMin";
    public static final String BUDGET_MAX = "budgetMax";
    public static final String WORLD_CASH_MIN = "cashMin";
    public static final String WORLD_CASH_MAX = "cashMax";
    private boolean noErrors = true;

    public AdvancedMovieSearchAction(ActionContext context, Grant requiredGrant) {
        actionContext = context;
    }

    @Override
    public Element execute() throws ActionExecutionException {
        try {
            Element response = XMLHelper.createElement(Response.RESPONSE);
            Element searchFormElement = createSearchFormElement();
            XMLHelper.addChild(response, searchFormElement);

            boolean doSearch = !isSearchingRequestEmpty();
            if (doSearch && noErrors) {
                Searcher searcher = searchers.get(MOVIE);
                SearchContext context = getSearchContext();
                Element foundResult = searcher.getResult(context);
                XMLHelper.addChild(response, foundResult);
            }

            return response;
        } catch (SystemException ex) {
            throw new ActionExecutionException(Labels.getLabel(Labels.CANNOT_EXECUTE_ACTION), ex);
        }
    }

    private Element createSearchFormElement() throws SystemException {
        Element form = XMLHelper.createElement(Response.ENTITY);
        form.setAttribute(Response.EDIT, "true");

        Map<String, String> validationMessages = getValidationMessages();
        noErrors = validationMessages.isEmpty();

        String title = StringUtil.getValidValue(actionContext.getTextParameter(TITLE));
        String countries = StringUtil.getValidValue(actionContext.getTextParameter(COUNTRIES));
        String genre = StringUtil.getValidValue(actionContext.getTextParameter(GENRE));
        String person = StringUtil.getValidValue(actionContext.getTextParameter(PERSON));
        String studio = StringUtil.getValidValue(actionContext.getTextParameter(STUDIO));
        String ratingMin = StringUtil.getValidValue(actionContext.getTextParameter(RATING_MIN));
        String ratingMax = StringUtil.getValidValue(actionContext.getTextParameter(RATING_MAX));
        String description = StringUtil.getValidValue(actionContext.getTextParameter(DESCRIPTION));
        String budgetMin = StringUtil.getValidValue(actionContext.getTextParameter(BUDGET_MIN));
        String budgetMax = StringUtil.getValidValue(actionContext.getTextParameter(BUDGET_MAX));
        String cashMin = StringUtil.getValidValue(actionContext.getTextParameter(WORLD_CASH_MIN));
        String cashMax = StringUtil.getValidValue(actionContext.getTextParameter((WORLD_CASH_MAX)));

        XMLHelper.addChild(form, XMLHelper.createHeader(Labels.getLabel(Labels.MOVIE_SEARCHING_HEADER)));
        XMLHelper.addChild(form, XMLHelper.createTextField(Labels.getLabel(Labels.MOVIE_TITLE), title, TITLE));
        XMLHelper.addChild(form, XMLHelper.createTextField(Labels.getLabel(Labels.MOVIE_COUNTRIES_SEARCH_FIELD_MESSAGE), countries, COUNTRIES));
        XMLHelper.addChild(form, XMLHelper.createTextField(Labels.getLabel(Labels.MOVIE_GENRES), genre, GENRE));
        XMLHelper.addChild(form, XMLHelper.createTextField(Labels.getLabel(Labels.PERSON_NAME), person, PERSON));
        XMLHelper.addChild(form, XMLHelper.createTextField(Labels.getLabel(Labels.MOVIE_STUDIO), studio, STUDIO));
        XMLHelper.addChild(form, XMLHelper.createTextField(Labels.getLabel(Labels.MOVIE_RATING_FROM), ratingMin, RATING_MIN, validationMessages.get(RATING_MIN)));
        XMLHelper.addChild(form, XMLHelper.createTextField(Labels.getLabel(Labels.MOVIE_RATING_TO), ratingMax, RATING_MAX, validationMessages.get(RATING_MAX)));
        XMLHelper.addChild(form, XMLHelper.createTextField(Labels.getLabel(Labels.MOVIE_DESCRIPTION), description, DESCRIPTION));
        XMLHelper.addChild(form, XMLHelper.createTextField(Labels.getLabel(Labels.MOVIE_BUDGET_FROM), budgetMin, BUDGET_MIN, validationMessages.get(BUDGET_MIN)));
        XMLHelper.addChild(form, XMLHelper.createTextField(Labels.getLabel(Labels.MOVIE_BUDGET_TO), budgetMax, BUDGET_MAX, validationMessages.get(BUDGET_MAX)));
        XMLHelper.addChild(form, XMLHelper.createTextField(Labels.getLabel(Labels.MOVIE_CASH_FROM), cashMin, WORLD_CASH_MIN, validationMessages.get(WORLD_CASH_MIN)));
        XMLHelper.addChild(form, XMLHelper.createTextField(Labels.getLabel(Labels.MOVIE_CASH_TO), cashMax, WORLD_CASH_MAX, validationMessages.get(WORLD_CASH_MAX)));
        //XMLHelper.addChild(form, XMLHelper.createButton(Labels.getLabel(Labels.SEARCH_BUTTON), ADVANCED_MOVIE_SEARCH));
        XMLHelper.addChild(form, XMLHelper.createImageButton(Image.getImage(Image.SEARCH), ADVANCED_MOVIE_SEARCH));

        return form;
    }

    private boolean isSearchingRequestEmpty() throws SystemException {
        String showFormOnly = actionContext.getTextParameter(SHOW_SEARCH_FORM_ONLY);
        return StringUtil.isEmpty(showFormOnly) ? false : !showFormOnly.equalsIgnoreCase("false");
    }

    @Override
    protected SearchContext createEmptySearchContext() {
        return new SearchContext(false);
    }

    @Override
    protected void fillContextWithSearchingParameters(SearchContext context) throws SystemException {
        String title = StringUtil.getValidValue(actionContext.getTextParameter(TITLE));
        context.addSearchParameter(TITLE, title);
        String countries = StringUtil.getValidValue(actionContext.getTextParameter(COUNTRIES));
        context.addSearchParameter(COUNTRIES, countries);
        String genre = StringUtil.getValidValue(actionContext.getTextParameter(GENRE));
        context.addSearchParameter(GENRE, genre);
        String person = StringUtil.getValidValue(actionContext.getTextParameter(PERSON));
        context.addSearchParameter(PERSON, person);
        String studio = StringUtil.getValidValue(actionContext.getTextParameter(STUDIO));
        context.addSearchParameter(STUDIO, studio);
        String ratingMin = StringUtil.getValidValue(actionContext.getTextParameter(RATING_MIN));
        context.addSearchParameter(RATING_MIN, ratingMin);
        String ratingMax = StringUtil.getValidValue(actionContext.getTextParameter(RATING_MAX));
        context.addSearchParameter(RATING_MAX, ratingMax);
        String description = StringUtil.getValidValue(actionContext.getTextParameter(DESCRIPTION));
        context.addSearchParameter(DESCRIPTION, description);
        String budgetMin = StringUtil.getValidValue(actionContext.getTextParameter(BUDGET_MIN));
        context.addSearchParameter(BUDGET_MIN, budgetMin);
        String budgetMax = StringUtil.getValidValue(actionContext.getTextParameter(BUDGET_MAX));
        context.addSearchParameter(BUDGET_MAX, budgetMax);
        String cashMin = StringUtil.getValidValue(actionContext.getTextParameter(WORLD_CASH_MIN));
        context.addSearchParameter(WORLD_CASH_MIN, cashMin);
        String cashMax = StringUtil.getValidValue(actionContext.getTextParameter(WORLD_CASH_MAX));
        context.addSearchParameter(WORLD_CASH_MAX, cashMax);

        context.setActionName(ADVANCED_MOVIE_SEARCH);
    }

    private Map<String, String> getValidationMessages() throws SystemException {
        Map<String, String> messages = new HashMap<String, String>();
        String ratingMinString = actionContext.getTextParameter(RATING_MIN);
        if (!StringUtil.isEmpty(ratingMinString)) {
            if (!StringUtil.isDouble(ratingMinString)) {
                messages.put(RATING_MIN, Labels.getLabel(Labels.VALUE_MUST_BE_DECIMAL_MESSAGE));
            }
        }
        String ratingMaxString = actionContext.getTextParameter(RATING_MAX);
        if (!StringUtil.isEmpty(ratingMaxString)) {
            if (!StringUtil.isDouble(ratingMaxString)) {
                messages.put(RATING_MAX, Labels.getLabel(Labels.VALUE_MUST_BE_DECIMAL_MESSAGE));
            }
        }
        String budgetMinString = actionContext.getTextParameter(BUDGET_MIN);
        if (!StringUtil.isEmpty(budgetMinString)) {
            if (!StringUtil.isInteger(budgetMinString)) {
                messages.put(BUDGET_MIN, Labels.getLabel(Labels.VALUE_MUST_BE_INTEGER_MESSAGE));
            }
        }
        String budgetMaxString = actionContext.getTextParameter(BUDGET_MAX);
        if (!StringUtil.isEmpty(budgetMaxString)) {
            if (!StringUtil.isInteger(budgetMaxString)) {
                messages.put(BUDGET_MAX, Labels.getLabel(Labels.VALUE_MUST_BE_INTEGER_MESSAGE));
            }
        }
        String cashtMinString = actionContext.getTextParameter(WORLD_CASH_MIN);
        if (!StringUtil.isEmpty(cashtMinString)) {
            if (!StringUtil.isInteger(cashtMinString)) {
                messages.put(WORLD_CASH_MIN, Labels.getLabel(Labels.VALUE_MUST_BE_INTEGER_MESSAGE));
            }
        }
        String cashtMaxString = actionContext.getTextParameter(WORLD_CASH_MAX);
        if (!StringUtil.isEmpty(cashtMaxString)) {
            if (!StringUtil.isInteger(cashtMaxString)) {
                messages.put(WORLD_CASH_MAX, Labels.getLabel(Labels.VALUE_MUST_BE_INTEGER_MESSAGE));
            }
        }
        return messages;
    }
}
